<?php

namespace app\controller\admin\module\role;

use app\controller\admin\module\AdminBaseController;
use think\exception\ValidateException;
use think\response\Json;
use think\response\View;

/**
 * 角色管理
 * @auth-name 角色管理
 * @auth-alias role
 */
class Index extends AdminBaseController
{
    protected string $modelName = 'gadmin';

    /**
     * @auth-name 主页
     * @auth-alias index
     * @return View
     */
    public function index(): View
    {
        return fetch('/admin/role/index');
    }

    /**
     * @auth-name 列表
     * @auth-alias list
     * @return Json
     */
    public function list(): Json
    {
        return json($this->model->getPageList([], 'id, name, status, addtime', ['addtime' => 'desc']));
    }

    /**
     * @auth-name 添加页面
     * @auth-alias add
     * @return View
     */
    public function add(): View
    {
        return fetch('/admin/role/add', ['menuList' => $this->getMenuList()]);
    }

    /**
     * @auth-name 添加提交
     * @auth-alias add
     * @auth-request-method post
     * @return Json
     */
    public function addPost(): Json
    {
        $name = values('name');   //角色名
        $mid = values('mid', []);   //菜单权限
        try {
            $this->validate([
                'name' => $name,
                'mid' => $mid,
            ],[
                'name|角色名' => ['require'],
                'mid|菜单权限' => ['require'],
            ]);
            //开启事务
            $this->model->startTrans();
            $gid = $this->model->add([
                'name' => $name,
                'status' => values('status', 2),    //是否启用
                'addtime' => time(),
            ], true);
            if(empty($gid)){
                throw new ValidateException('新增失败');
            }
            $data = [];
            foreach($mid as $k => $v){
                $data[$k] = [
                    'gid' => $gid,
                    'mid' => $v,
                    'addtime' => time(),
                ];
            }
            $res = Model('gadminMenu')->addAll($data);
            if(!$res){
                throw new ValidateException('新增失败');
            }
            putAdminLog("新增角色[$gid]");
            $this->model->commit();
            return responseMsg('新增成功', 200);
        }catch (ValidateException $e){
            $this->model->rollback();
            return responseMsg($e->getError());
        }
    }

    /**
     * @auth-name 编辑页面
     * @auth-alias edit
     * @return View
     */
    public function edit(): View
    {
        $id = values('get.id', 0);
        empty($id) and missPage();
        $info = $this->model->getInfo(['id' => $id], 'id, name, status');
        empty($info) and errorData();
        $myMenuArray = Model('gadminMenu')->getList(['gid' => $id], 'mid');
        $myMenuArray = !empty($myMenuArray) ? array_column($myMenuArray, 'mid') : [];
        return fetch('/admin/role/edit', [
            'info' => $info,
            'menuList' => $this->getMenuList(),
            'myMenuArray' => $myMenuArray
        ]);
    }

    /**
     * @auth-name 编辑提交
     * @auth-alias edit
     * @auth-request-method post
     * @return Json
     */
    public function editPost(): Json
    {
        $id = values('post.id');   //角色名
        if(empty($id)){
            return responseMsg('缺少参数');
        }
        $info = $this->model->getInfo(['id' => $id], 'id, name, status');
        if(empty($info)){
            return responseMsg('数据错误');
        }
        $name = values('post.name');   //角色名
        $mid = values('post.mid', []);   //菜单权限
        $status = values('post.status', 2); //是否启用 1是启用 2是禁用
        try {
            $this->validate([
                'name' => $name,
            ],[
                'name|角色名' => ['require'],
            ]);
            $this->model->startTrans();
            $myMid = Model('gadminMenu')->getList(['gid' => $id], 'mid');
            $oldMid = !empty($myMid) ? array_column($myMid, 'mid') : [];
            [$create, $delete] = $this->handlerMid($oldMid, $mid);
            if(!empty($create)){
                $data = [];
                foreach($create as $v){
                    $data[] = [
                        'gid' => $id,
                        'mid' => $v,
                        'addtime' => time(),
                    ];
                }
                $res = Model('gadminMenu')->addAll($data);
                if(!$res){
                    throw new ValidateException('新增失败');
                }
            }
            if(!empty($delete)){
                if(!Model('gadminMenu')->del(['gid' => $id, 'mid' => $delete])){
                    throw new ValidateException('删除失败');
                }
            }
            if($info['name'] != $name or $info['status'] != $status) {
                if (!$this->model->edit(['id' => $id], [
                    'name' => $name,
                    'status' => $status,
                ])) {
                    throw new ValidateException('编辑失败');
                }
            }
            putAdminLog("编辑角色信息[{$info['id']}]");
            $this->model->commit();
            return responseMsg('编辑成功', 200);
        }catch (ValidateException $e){
            $this->model->rollback();
            return responseMsg($e->getError());
        }
    }

    private function handlerMid($old, $new): array
    {
        sort($old);
        sort($new);
        $create = $delete = [];
        if($old != $new) {
            if (empty($new)) {
                $delete = $old;
            } else if (empty($old)) {
                $create = $new;
            } else {
                foreach ($new as $v) {
                    if (!in_array($v, $old)) {
                        $create[] = $v;
                    }
                }
                foreach ($old as $v) {
                    if (!in_array($v, $new)) {
                        $delete[] = $v;
                    }
                }
            }
        }
        return [$create, $delete];
    }

    /**
     * @auth-name 删除
     * @auth-alias del
     * @auth-request-method delete
     * @return Json
     */
    public function del(): Json
    {
        $idx = values('idx', []);
        if(!empty($idx)){
            $list = $this->model->getList(['id' => $idx]);
            if(empty($list)){
                return responseMsg('未找到角色信息');
            }
            if($this->model->del(['id' => $idx])){
                Model('gadminMenu')->del(['gid' => $idx]);
                putAdminLog("删除角色[" . json_encode($list) . "]");
                return responseMsg('操作成功', 200);
            }
        }
        return responseMsg('操作失败，请稍后重试');
    }

    /**
     * 是否启用
     * @auth-name 状态修改
     * @auth-alias state
     * @auth-request-method post
     * @return Json
     */
    public function state(): Json
    {
        $idx = values('idx', []);
        $status = values('status', 1);
        if(!empty($idx)){
            $res = $this->model->edit(['id' => $idx], ['status' => $status]);
            if($res){
                putAdminLog("修改角色信息[" . json_encode($idx) . "]");
                return responseMsg('操作成功', 200);
            }
        }
        return responseMsg('操作失败，请稍后重试');
    }


    /**
     * 获取菜单列表
     * @return array
     */
    private function getMenuList(): array
    {
        $arr = Model('menu')->getList(['is_home_page' => 0], 'id, name, pid, level, sort, status', 'sort desc');
        array_multisort( array_column($arr, 'level'), SORT_ASC,  array_column($arr, 'sort'), SORT_DESC, $arr);
        return infiniteCategoryChild($arr);
    }
}